package com.iflysse.controller;

import com.alibaba.fastjson.JSONObject;
import com.iflysse.common.ResultEnum;
import com.iflysse.common.RoleEnum;
import com.iflysse.pojo.bo.CommonBoResp;
import com.iflysse.pojo.bo.req.*;
import com.iflysse.pojo.bo.resp.*;
import com.iflysse.pojo.vo.common.CommonVoResp;
import com.iflysse.pojo.vo.req.*;
import com.iflysse.pojo.vo.resp.*;
import com.iflysse.services.StudentService;
import com.iflysse.services.TeacherService;
import com.iflysse.services.UserService;
import com.iflysse.util.CommonUtil;
import com.iflysse.util.FileUpdateUtil;
import com.iflysse.util.JwtUtil;
import com.iflysse.util.ThreeDesUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;

@RestController
@RequestMapping("/user")
@Api(value = "公用用户模块接口")
@Log4j
public class UserController {


    @Autowired
    private UserService userService;

    @Autowired
    private TeacherService teacherService;

    @Autowired
    private StudentService studentService;


    /**
     * 校验链接是否有效
     */
    @PostMapping("/checkEmailLinkIsOk")
    @ApiOperation(value = "校验链接是否有效")
    public CheckEmailLinkIsOkVoResp doCheckEmailLinkIsOk(CheckEmailLinkIsOkVoReq checkEmailLinkIsOkVoReq,HttpServletRequest request){

        CheckEmailLinkIsOkVoResp checkEmailLinkIsOkVoResp=new CheckEmailLinkIsOkVoResp();
        try{
            String info=  checkEmailLinkIsOkVoReq.getInfo();
            log.info("校验链接是否有效参数："+info);
            String json= ThreeDesUtil.decode3Des(ThreeDesUtil.threeDesKey,info);
            log.info("校验链接是否有效解密后参数："+json);

            SectionResp sectionResp=JSONObject.parseObject(json,SectionResp.class);
            log.info("校验链接是否有效转成对象后参数："+sectionResp);

            if(Long.valueOf(sectionResp.getExpireDate())<System.currentTimeMillis()){//到期了
                checkEmailLinkIsOkVoResp.setCode(ResultEnum.LINKISERROR.getCode());
                checkEmailLinkIsOkVoResp.setMsg(ResultEnum.LINKISERROR.getMsg());
            }else{//有效期内
                CheckEmailLinkIsOkResp checkEmailLinkIsOkResp=new CheckEmailLinkIsOkResp();
                checkEmailLinkIsOkResp.setAccountId(sectionResp.getUserId());
                checkEmailLinkIsOkVoResp.setResult(checkEmailLinkIsOkResp);
                checkEmailLinkIsOkVoResp.setCode(ResultEnum.SUCCESS.getCode());
                checkEmailLinkIsOkVoResp.setMsg(ResultEnum.SUCCESS.getMsg());
            }

            log.info("校验链接是否有效响应bean:"+checkEmailLinkIsOkVoResp);
            return checkEmailLinkIsOkVoResp;
        }catch (Exception e){
            log.error("校验链接是否有效出现异常："+e);
            CommonUtil.printError(checkEmailLinkIsOkVoResp);
            return checkEmailLinkIsOkVoResp;
        }


    }








    /**
     * 修改头像
     * @throws IOException
     */
    @PostMapping("/updateUserHeadImage")
    @ApiOperation(value = "修改头像接口")
    public CommonVoResp doUpdateUserHeadImage(@RequestParam(value = "headImagePath") MultipartFile file, UserHeadImageVoReq userHeadImageVoReq){
        CommonVoResp commonVoResp=new CommonVoResp();
        try{


            log.info("用户头像修改参数："+userHeadImageVoReq);
            String path=FileUpdateUtil.fileUploadToBoot(file,FileUpdateUtil.headImgSuffix);

            if("1".equals(userHeadImageVoReq.getRole())){//老师
                UserHeadImageBoReq userHeadImageBoReq=CommonUtil.objToObj(userHeadImageVoReq,UserHeadImageBoReq.class);
                userHeadImageBoReq.setHeadImagePath(path);
                log.info("用户头像修改调用业务接口参数："+userHeadImageBoReq);
                CommonBoResp commonBoResp= teacherService.updateHeadImage4Teacher(userHeadImageBoReq);
                CommonUtil.printBoResultToVoResult(commonBoResp,commonVoResp);
            }else if("2".equals(userHeadImageVoReq.getRole())){//学生
                StudentHeadImageBoReq studentHeadImageBoReq=CommonUtil.objToObj(userHeadImageVoReq,StudentHeadImageBoReq.class);
                studentHeadImageBoReq.setStudentId(userHeadImageVoReq.getId());
                studentHeadImageBoReq.setHeadImagePath(path);
                log.info("用户头像修改调用学生业务接口参数："+studentHeadImageBoReq);
                CommonBoResp commonBoResp=  studentService.updateStudentHeadImage(studentHeadImageBoReq);
                CommonUtil.printBoResultToVoResult(commonBoResp,commonVoResp);
            }


            log.info("用户头像修改响应bean:"+commonVoResp);
            return commonVoResp;
        }catch (Exception e){
            log.info("用户头像修改出现异常:"+e);
            CommonUtil.printError(commonVoResp);
            return commonVoResp;
        }
    }





    @PostMapping("/updateUserInfo")
    @ApiOperation(value = "修改用户信息接口")
    public CommonVoResp doUpdateUserInfo(UpdateUserInfoVoReq updateUserInfoVoReq){
        CommonVoResp commonVoResp=new CommonVoResp();
        try{

            log.info("修改用户信息参数bean:"+updateUserInfoVoReq);
            if("1".equals(updateUserInfoVoReq.getRole())){//老师端修改个人信息
                TeacherInfoBoReq teacherInfoBoReq= CommonUtil.objToObj(updateUserInfoVoReq, TeacherInfoBoReq.class);
                teacherInfoBoReq.setTeacherId(updateUserInfoVoReq.getUserId());

                log.info("修改用户信息调用业务接口参数bean:"+teacherInfoBoReq);
                CommonBoResp commonBoResp= teacherService.updateTeacher(teacherInfoBoReq);
                CommonUtil.printBoResultToVoResult(commonBoResp,commonVoResp);

            }else if("2".equals(updateUserInfoVoReq.getRole())){//学生端修改个人信息
                StudentBoReq studentBoReq=CommonUtil.objToObj(updateUserInfoVoReq,StudentBoReq.class);
                studentBoReq.setStudentId(updateUserInfoVoReq.getUserId());
                studentBoReq.setStudent_name(updateUserInfoVoReq.getName());
                studentBoReq.setNick_name(updateUserInfoVoReq.getNickName());
                studentBoReq.setPersonal_signature(updateUserInfoVoReq.getPersonalSignature());
                studentBoReq.setHobbies(updateUserInfoVoReq.getHobby());


                log.info("修改用户信息调用业务接口参数bean:"+studentBoReq);
                CommonBoResp commonBoResp= studentService.updateStudentInfo(studentBoReq);
                CommonUtil.printBoResultToVoResult(commonBoResp,commonVoResp);
            }
            log.info("修改用户信息响应bean:"+commonVoResp);
            return commonVoResp;
        }catch (Exception e){
            log.error("修改用户信息出现异常："+e);
            CommonUtil.printError(commonVoResp);
            return commonVoResp;
        }
    }





    /**
     * 查询用户个人信息接口
     * @param queryUserInfoVoReq
     * @return
     */
    @PostMapping("/queryUserInfo")
    @ApiOperation(value = "查询用户信息，老师端学生端共有")
    public QueryUserInfoVoResp queryUserInfo(QueryUserInfoVoReq queryUserInfoVoReq){

        QueryUserInfoVoResp queryUserInfoVoResp=new QueryUserInfoVoResp();
        try{

            log.info("查询用户个人信息接口参数bean:"+queryUserInfoVoReq);

            if("1".equals(queryUserInfoVoReq.getRole())){//老师
                TeacherIdBoReq teacherIdBoReq=new TeacherIdBoReq();
                teacherIdBoReq.setTeacherId(queryUserInfoVoReq.getUserId());
                TeacherInfoBoRes teacherInfoBoRes= teacherService.getTeacherInfoByTeacherId(teacherIdBoReq);
                QueryUserInfoResp result=  CommonUtil.objToObj(teacherInfoBoRes,QueryUserInfoResp.class);
                result.setBaseImg(FileUpdateUtil.prefixResources+teacherInfoBoRes.getHeadImage());

                queryUserInfoVoResp.setResult(result);
            }else if("2".equals(queryUserInfoVoReq.getRole())){//学生
                StudentIdBoReq studentIdBoReq=new StudentIdBoReq();
                studentIdBoReq.setStudentId(queryUserInfoVoReq.getUserId());
                StudentInfoBoResp studentInfoBoResp= studentService.getStudentInfoByStudentId(studentIdBoReq);
                QueryUserInfoResp result=CommonUtil.objToObj(studentInfoBoResp,QueryUserInfoResp.class);
                result.setBaseImg(FileUpdateUtil.prefixResources+studentInfoBoResp.getHeadImage());
                if (studentInfoBoResp.getHobbies()!=null&&!"".equals(studentInfoBoResp.getHobbies())){
                    result.setHobby(Arrays.asList(studentInfoBoResp.getHobbies().split(",")));
                }else{
                    result.setHobby(new ArrayList<>());
                }

                queryUserInfoVoResp.setResult(result);
            }

            queryUserInfoVoResp.setMsg(ResultEnum.SUCCESS.getMsg());
            queryUserInfoVoResp.setCode(ResultEnum.SUCCESS.getCode());
            log.info("查询用户个人信息接口响应bean:"+queryUserInfoVoResp);
            return queryUserInfoVoResp;
        }catch (Exception e){
            log.info("查询用户个人信息接口出现异常："+e);
            CommonUtil.printError(queryUserInfoVoResp);
            return queryUserInfoVoResp;
        }

    }




    /**
     * 重置密码操作
     * @param resetPasswordVoReq
     * @return
     */
    @PostMapping("/resetPassword")
    @ApiOperation(value = "用户重置密码接口")
    public CommonVoResp resetPassword(ResetPasswordVoReq resetPasswordVoReq,HttpServletRequest request){
        CommonVoResp commonVoResp=new CommonVoResp();
        try{
            log.info("重置密码的请求参数："+resetPasswordVoReq);
            if (resetPasswordVoReq.getConfirmPassword()==null||resetPasswordVoReq.getPassWord()==null||
                    !resetPasswordVoReq.getPassWord().equals(resetPasswordVoReq.getConfirmPassword())){
                commonVoResp.setCode(ResultEnum.ERRORPASSWORD.getCode());
                commonVoResp.setMsg(ResultEnum.ERRORPASSWORD.getMsg());

                return commonVoResp;
            }

            String code=(String)request.getSession().getAttribute(resetPasswordVoReq.getCodeId());
            if(resetPasswordVoReq.getCode()==null||!resetPasswordVoReq.getCode().equals(code)){
                commonVoResp.setCode(ResultEnum.CODEERROR.getCode());
                commonVoResp.setMsg(ResultEnum.CODEERROR.getMsg());
                return commonVoResp;
            }

            UserAccountIdAndPasswordBoReq userAccountIdAndPasswordBoReq=new UserAccountIdAndPasswordBoReq();
            userAccountIdAndPasswordBoReq.setAccountId(resetPasswordVoReq.getUserId());
            userAccountIdAndPasswordBoReq.setPassword(resetPasswordVoReq.getPassWord());
            CommonBoResp commonBoResp= userService.updateUserPassword(userAccountIdAndPasswordBoReq);
            CommonUtil.printBoResultToVoResult(commonBoResp,commonVoResp);
            log.info("重置密码操作响应bean:"+commonVoResp);

            return commonVoResp;

        }catch (Exception e){
            log.error("重置密码操作出现异常："+e);
            CommonUtil.printError(commonVoResp);
            return commonVoResp;
        }
    }


    /**
     * 找回密码操作
     * @param retrievePasswordVoReq
     * @return
     */
    @PostMapping("/retrievePassword")
    @ApiOperation(value = "用户找回密码接口")
    public CommonVoResp retrievePassword(RetrievePasswordVoReq retrievePasswordVoReq,HttpServletRequest request){
        CommonVoResp commonVoResp=new CommonVoResp();
        try{
            log.info("用户找回密码接口参数："+retrievePasswordVoReq);
            //校验验证码是否正确
            String code=(String)  request.getSession().getAttribute(retrievePasswordVoReq.getCodeId());
            if(!retrievePasswordVoReq.getCode().equals(code)){
                commonVoResp.setCode(ResultEnum.CODEERROR.getCode());
                commonVoResp.setMsg(ResultEnum.CODEERROR.getMsg());
                log.info("找回密码操作响应bean:"+commonVoResp);

                return commonVoResp;
            }

            //校验用户名和邮箱是否正确;获取用户编号
            UsernameAndEmailBoReq usernameAndEmailBoReq= CommonUtil.objToObj(retrievePasswordVoReq, UsernameAndEmailBoReq.class);
            log.info("找回密码操作调用业务接口参数："+usernameAndEmailBoReq);
            UserAccountIdBoResp userAccountIdBoResp= userService.checkUserNameAndEmail(usernameAndEmailBoReq);
            String accountId=userAccountIdBoResp.getAccountId();

            if (accountId!=null&&!"".equals(accountId)){
                //账户编号不为空时拼接邮件内容
                Calendar c=Calendar.getInstance();
                c.add(Calendar.MINUTE,60);
                long time=c.getTime().getTime();

                SectionResp sectionResp=new SectionResp();
                sectionResp.setUserId(accountId);
                sectionResp.setExpireDate(String.valueOf(time));
                String json=  JSONObject.toJSONString(sectionResp);

                String encode = ThreeDesUtil.encode3Des(ThreeDesUtil.threeDesKey, json);
                String email= CommonUtil.bufferEmailInfo(encode);
                CommonUtil.sendMail(retrievePasswordVoReq.getEmail(),email);
                commonVoResp.setCode(ResultEnum.SUCCESS.getCode());
                commonVoResp.setMsg(ResultEnum.SUCCESS.getMsg());

            }else{
                commonVoResp.setCode(ResultEnum.NOPARAMETER.getCode());
                commonVoResp.setMsg(ResultEnum.NOPARAMETER.getMsg());

            }

            log.info("找回密码操作响应bean:"+commonVoResp);
            return commonVoResp;

        }catch (Exception e){
            log.error("找回密码操作出现异常："+e);
            CommonUtil.printError(commonVoResp);
            return commonVoResp;
        }
    }



    @PostMapping("/login")
    @ApiOperation(value = "用户登录接口")
    public UserVoResp login(UserVoReq userVoReq,HttpServletRequest request){

        UserVoResp userVoResp = new UserVoResp();
        log.info("登录接口的前端请求参数bean:" + userVoReq);
        try {
            String userName = userVoReq.getUserName();
            String passWord = userVoReq.getPassWord();
            String code = userVoReq.getCode();
            String codeId = userVoReq.getCodeId();
            if ("".equals(userName) || userName == null ||
                    "".equals(passWord) || passWord == null ||
                    "".equals(code) || code == null ||
                    "".equals(codeId) || codeId == null) {

                userVoResp.setCode(ResultEnum.NOPARAMETER.getCode());
                userVoResp.setMsg(ResultEnum.NOPARAMETER.getMsg());
                log.info("登录接口响应bean信息：" + userVoResp);
                return userVoResp;
            }


            //校验验证码是否正确
            String sessionCode = (String) request.getSession().getAttribute(codeId);
            if (!code.equals(sessionCode)) {
                userVoResp.setCode(ResultEnum.CODEERROR.getCode());
                userVoResp.setMsg(ResultEnum.CODEERROR.getMsg());
                log.info("登录接口响应bean信息：" + userVoResp);
                return userVoResp;
            }

            UserBoReq userBoReq = CommonUtil.objToObj(userVoReq, UserBoReq.class);
            log.info("调用业务层的登录接口方法请求参数："+userBoReq);
            UserBoResp userBoResp=userService.login(userBoReq);
            log.info("调用业务层的登录接口方法的响应bean信息"+userBoResp);
            if (userBoResp==null){
                userVoResp.setCode(ResultEnum.ACCOUNTERROR.getCode());
                userVoResp.setMsg(ResultEnum.ACCOUNTERROR.getMsg());
                log.info("登录接口响应业务层返回空对象：" + userVoResp);
                return userVoResp;
            }

            if(userBoResp.getUserId()==null||userBoResp.getRole()==null){
                userVoResp.setCode(ResultEnum.ACCOUNTERROR.getCode());
                userVoResp.setMsg(ResultEnum.ACCOUNTERROR.getMsg());
                log.info("登录接口响应bean信息：" + userVoResp);
                return userVoResp;
            }

            //根据accountId和角色生成token信息
            String token= JwtUtil.createToken(userBoResp.getUserId(),userBoResp.getRole());

            //根据userBoResp 中的userId(账户编号)和角色查询对应的老师编号或者学生编号

            UserTeacherInfoBoResp userTeacherInfoBoResp= userService.queryIdByAccountIdAndRole(userBoResp.getUserId(),userBoResp.getRole());

            UserResp userResp=new UserResp();
            userResp.setToken(token);
            userResp.setRole(userBoResp.getRole());
            if(userBoResp.getRole().equals(RoleEnum.ROLETEACHER.getRoleId())){
                userResp.setUserId(userTeacherInfoBoResp.getTeacherId());
            }else if(userBoResp.getRole().equals(RoleEnum.ROLESTUDENT.getRoleId())){
                userResp.setUserId(userTeacherInfoBoResp.getStudentId());
            }
            userVoResp.setMsg(ResultEnum.SUCCESS.getMsg());
            userVoResp.setCode(ResultEnum.SUCCESS.getCode());
            userVoResp.setResult(userResp);
            log.info("登录接口响应bean信息：" + userVoResp);
            return userVoResp;

        }catch (Exception e){
            log.error("登录接口出现异常，信息为："+e);
            userVoResp.setCode(ResultEnum.ERROR.getCode());
            userVoResp.setMsg(ResultEnum.ERROR.getMsg());
            log.info("登录接口响应bean信息："+userVoResp);
            return userVoResp;
        }
    }


    /**
     * 图片验证码
     * @param request
     * @param response
     * @throws IOException
     */
    @PostMapping("/code")
    @ApiOperation(value = "图形验证码")
    public CodeVoResp createCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
        log.info("验证码请求");

        //创建一张缓存图片
        BufferedImage image=new BufferedImage(100, 30, BufferedImage.TYPE_INT_RGB);

        //根据图片对象获取出图片的绘制对象
        Graphics g=image.getGraphics();
        //根据绘制对象来给图片增加背景颜色
        g.setColor(Color.WHITE);
        //根据绘制对象来确定背景颜色的范围
        g.fillRect(0,0 , 100, 30);

        //往这张图片画的东西（干扰线，数字）

        g.setColor(Color.YELLOW);
        //随机生成一个数
        Random r=new Random();
        for(int i=0;i<20;i++) {
            int x1=r.nextInt(90);
            int y1=r.nextInt(30);
            int newX=r.nextInt(90);
            int newY=r.nextInt(30);
            //画干扰线
            g.drawLine(x1, y1, newX, newY);
        }

        //往图片中绘制验证码  4
        g.setColor(Color.GREEN);

        StringBuffer sbCode=new StringBuffer();
        int x=20;
        for(int i=0;i<4;i++) {
            int txt=r.nextInt(10);
            String str=String.valueOf(txt);
            g.drawString(str, x, 20);//
            sbCode.append(str);
            x=x+20;
        }

        // 生成验证码的唯一标识
        String codeId= UUID.randomUUID().toString().replaceAll("-","");

        log.info("验证码编号："+codeId+"对应的验证码为："+sbCode.toString());
        // 设置session的有效期
        //将验证码存到session中，方便登录时来获取这个验证去校验用户登陆时所输入的验证码是否正确
        HttpSession session=request.getSession();
//        session.setMaxInactiveInterval(300);//5分钟有效
        session.setAttribute(codeId, sbCode.toString());

        String code=(String)session.getAttribute(codeId);
        log.info("codeId:"+codeId+"——>code:"+sbCode.toString());

//        BASE64Encoder encoder = new BASE64Encoder();

        ByteArrayOutputStream baos = new ByteArrayOutputStream();//io流
        ImageIO.write(image, "gif", baos);//写入流中
        byte[] bytes = baos.toByteArray();//转换成字节
//        String png_base64 =  encoder.encodeBuffer(bytes).trim();//转换成base64串

        Base64.Encoder base64=Base64.getEncoder();

        byte [] img= base64.encode(bytes);

        String png_base64=new String(img);
        //删除 \r\n
        png_base64 = png_base64.replaceAll("\n", "").replaceAll("\r", "");

        log.info("验证码"+sbCode+"对应的base64码："+png_base64);

        CodeResp codeResp=new CodeResp();
        codeResp.setCodeId(codeId);
        codeResp.setBaseImage(CommonUtil.appendBaseToWebApp(png_base64,"gif"));

        CodeVoResp codeVoResp=new CodeVoResp();
        codeVoResp.setCode(ResultEnum.SUCCESS.getCode());
        codeVoResp.setMsg(ResultEnum.SUCCESS.getMsg());
        codeVoResp.setResult(codeResp);
        log.info("获取验证码的响应bean信息："+codeVoResp);
        return codeVoResp;

    }
}
